#pragma once

#include <httplib.h>
#include <spdlog/spdlog.h>
#include "../util/config.hh"
#include "../util/except.hh"

namespace WordMemory
{
    class Server
    {
    public:
        using business = std::function<void(const httplib::Request &, httplib::Response &)>;

        enum BusType {
            GET = 0,
            POST,
            PUT,
            DELETE
        };

        static Server &instance()
        {
            static Server svr;
            return svr;
        }

    private:
        Server()
            : _ip("0.0.0.0")
            , _port(Config::instance().svr_port())
        {}

        Server(const Server &) = delete;
        Server &operator=(const Server &) = delete;

    public:
        template <size_t type>
        void regist(const std::string& name, business bus)
        {
            if (type == BusType::GET) _svr.Get(name, bus);
            else if (type == BusType::POST) _svr.Post(name, bus);
            else if (type == BusType::PUT) _svr.Put(name, bus);
            else if (type == BusType::DELETE) _svr.Delete(name, bus);
            else throw ServerExcept("regist: unknown bus_type");
        }

        void run()
        {
            spdlog::info("Http server started on {}", _port);

            if (!_svr.listen(_ip, _port))
                spdlog::error("Http server start failed on {}:{}", _ip, _port);
        }

    private:
        std::string _ip;
        uint16_t _port;
        httplib::Server _svr;
    };
}
